package boofbridgeimaj.image.feature.util;

import boofbridgeimaj.image.util.BoofToImaj;
import boofcv.abst.feature.detdesc.DetectDescribePoint;
import boofcv.struct.feature.TupleDesc_U8;
import boofcv.struct.image.ImageFloat32;
import georegression.struct.point.Point2D_F64;
import org.openimaj.feature.local.list.LocalFeatureList;
import org.openimaj.image.FImage;
import org.openimaj.image.feature.local.engine.Engine;
import org.openimaj.image.feature.local.keypoints.Keypoint;

/**
 * Wrapper class which allows {@link Engine} in OpenIMAJ to be used as a {@link DetectDescribePoint} in BoofCV.
 *
 * @author Peter Abeles
 */
public class EngineToDetectDescribePoint_F32_TU8 implements DetectDescribePoint<ImageFloat32,TupleDesc_U8> {

	Engine<Keypoint, FImage> engine;
	FImage imajInput;
	LocalFeatureList<Keypoint> points;
	int featureLength;
	// storage for point output
	Point2D_F64 point = new Point2D_F64();

	public EngineToDetectDescribePoint_F32_TU8(Engine<Keypoint, FImage> engine, int featureLength) {
		this.featureLength = featureLength;
		this.engine = engine;
	}

	@Override
	public TupleDesc_U8 createDescription() {
		return new TupleDesc_U8(featureLength);
	}

	@Override
	public TupleDesc_U8 getDescriptor(int index) {
		Keypoint kp = points.get(index);
		TupleDesc_U8 desc = createDescription();

		System.arraycopy(kp.getFeatureVector().values,0,desc.value,0,featureLength);

		return desc;
	}

	@Override
	public Class<TupleDesc_U8> getDescriptorType() {
		return TupleDesc_U8.class;
	}

	@Override
	public void detect(ImageFloat32 input) {
		imajInput = BoofToImaj.convert(input,imajInput);

		points = engine.findFeatures(imajInput);
	}

	@Override
	public int getNumberOfFeatures() {
		return points.size();
	}

	@Override
	public Point2D_F64 getLocation(int featureIndex) {
		Keypoint kp = points.get(featureIndex);
		point.set(kp.x,kp.y);
		return point;
	}

	@Override
	public double getScale(int featureIndex) {
		return points.get(featureIndex).getScale();
	}

	@Override
	public double getOrientation(int featureIndex) {
		return points.get(featureIndex).ori;
	}

	@Override
	public boolean hasScale() {
		return true;
	}

	@Override
	public boolean hasOrientation() {
		return true;
	}
}
